﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Org.Mentalis.Files;
using Microsoft.Win32;
using System.Windows;

namespace ArmoryViewer
{
    static class Settings
    {
        private static bool isAdmin = false; //based on whether registry read fails or not
        private static IniReader settings;

        //Settings variables
        private static bool handleAvProtocol;
        public static bool IsAdmin { get; private set; }
        /// <summary>
        /// Gets a value indicating whether we are installed.
        /// </summary>
        /// <value><c>true</c> if installed; otherwise, <c>false</c>.</value>
        public static bool Installed
        {
            get { return File.Exists(App.CurrentDirectory + "installed"); }
        }

        /// <summary>
        /// Gets or sets the armory URL.
        /// </summary>
        /// <value>The armory URL.</value>
        public static Uri ArmoryUrl { get; set; }
        /// <summary>
        /// Gets or sets a value indicating whether the application should hide when minimized.
        /// </summary>
        /// <value><c>true</c> if the application should hide when minimized; otherwise, <c>false</c>.</value>
        public static bool HideWhenMinimized { get; set; }
        /// <summary>
        /// Gets or sets a value indicating whether we should check for updates on startup.
        /// </summary>
        /// <value><c>true</c> if we should check for updates on startup; otherwise, <c>false</c>.</value>
        public static bool UpdateOnStartup { get; set; }
        /// <summary>
        /// Gets or sets a value indicating whether we should download sockets/enchants.
        /// </summary>
        /// <value><c>true</c> if we should download sockets/enchants; otherwise, <c>false</c>.</value>
        public static bool DownloadSockets { get; set; }
        /// <summary>
        /// Gets or sets the language.
        /// </summary>
        /// <value>The language.</value>
        public static string Language { get; set; }
        /// <summary>
        /// Gets or sets the type of the search.
        /// </summary>
        /// <value>The type of the search.</value>
        public static int SearchType { get; set; }
        /// <summary>
        /// Gets or sets a value indicating whether we should download achievements.
        /// </summary>
        /// <value><c>true</c> if we should download achievements; otherwise, <c>false</c>.</value>
        public static bool DownloadAchievements { get; set; }
        /// <summary>
        /// Gets or sets the update mirror.
        /// </summary>
        /// <value>The update mirror.</value>
        public static Uri UpdateMirror { get; set; }


        /// <summary>
        /// Gets or sets a value indicating whether we will handle the av protocol.
        /// </summary>
        /// <value><c>true</c> if we will handle the av protocol; otherwise, <c>false</c>.</value>
        public static bool HandleAvProtocol
        {
            get { return handleAvProtocol; }
            set
            {
                if (handleAvProtocol != value && isAdmin)
                {
                    handleAvProtocol = value;
                    RegistryKey registry = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Classes");
                    if (value)
                    {
                        try
                        {
                            RegistryKey av = registry.CreateSubKey("av");
                            av.SetValue("", "URL:Armory Viewer Protocol");
                            av.SetValue("URL Protocol", "", RegistryValueKind.String);
                            av.CreateSubKey("DefaultIcon").SetValue("", App.CurrentDirectory + "Armory Viewer.exe");
                            av.CreateSubKey("shell").CreateSubKey("open").CreateSubKey("command").SetValue("", App.CurrentDirectory + "Armory Viewer.exe \"%1\"");
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Could not access registry", MessageBoxButton.OK, MessageBoxImage.Error);   
                        }
                    }
                    else
                    {
                        registry.DeleteSubKeyTree("av");
                    }
                }
            }
        }

        static Settings() 
        {
            settings = new IniReader(App.CurrentDirectory + "settings.ini");
            isAdmin = false;
        }

        /// <summary>
        /// Loads the settings from the INI file
        /// </summary>
        public static void Load()
        {
            ArmoryUrl = new Uri(settings.ReadString("General", "ArmoryUrl", "http://www.wowarmory.com"));
            UpdateOnStartup = settings.ReadBoolean("General", "UpdateOnStartup", false);
            HideWhenMinimized = settings.ReadBoolean("General", "HideWhenMinimized", true);
            DownloadSockets = settings.ReadBoolean("General", "DownloadSockets", true);
            Language = settings.ReadString("General", "Language", "www");
            SearchType = settings.ReadInteger("General", "SearchType", 1);

            try
            {
                handleAvProtocol = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\Classes").OpenSubKey("av") != null;
                isAdmin = true;
            }
            catch
            {
                isAdmin = false;
                handleAvProtocol = false;
            }
            DownloadAchievements = settings.ReadBoolean("ArmoryViewer", "downloadAchievements", true);

            // Proxy
            switch (settings.ReadString("Proxy", "ProxyType", "None"))
            {
                case "None": Proxy.ProxyType = ProxyType.None; break;
                case "AutoDetect": Proxy.ProxyType = ProxyType.AutoDetect; break;
                case "Manual": Proxy.ProxyType = ProxyType.Manual; break;
            }
            Proxy.Address = settings.ReadString("Proxy", "Address", "");
            Proxy.Port = settings.ReadString("Proxy", "Port", "");
            Proxy.Username = settings.ReadString("Proxy", "Username", "");
            Proxy.Password = settings.ReadString("Proxy", "Password", "");

            // Advanced
            string mir = settings.ReadString("Advanced", "UpdateMirror", "http://sites.google.com/site/christianhood/armoryviewer/");
            if (mir[mir.Length - 1] != '/') mir += "/";
            UpdateMirror = new Uri(mir);
        }

        /// <summary>
        /// Saves the settings to the INI file.
        /// </summary>
        public static void Save()
        {
            settings.Write("General", "ArmoryUrl", ArmoryUrl.ToString());
            settings.Write("General", "UpdateOnStartup", UpdateOnStartup);
            settings.Write("General", "HideWhenMinimized", HideWhenMinimized);
            settings.Write("General", "DownloadSockets", DownloadSockets);
            settings.Write("General", "Language", Language);
            settings.Write("General", "SearchType", SearchType);
            settings.Write("General", "DownloadAchievements", DownloadAchievements);

            // Proxy
            settings.Write("Proxy", "ProxyType", Proxy.ProxyType.ToString());
            settings.Write("Proxy", "Address", Proxy.Address);
            settings.Write("Proxy", "Port", Proxy.Port);
            settings.Write("Proxy", "Username", Proxy.Username);
            settings.Write("Proxy", "Password", Proxy.Password);

            // Advanced
            settings.Write("Advanced", "UpdateMirror", UpdateMirror.AbsoluteUri);
        }

        /// <summary>
        /// The configured proxy type.
        /// </summary>
        public enum ProxyType
        {
            /// <summary>
            /// Do not use a proxy.
            /// </summary>
            None,
            /// <summary>
            /// Automatically detect the proxy to use.
            /// </summary>
            AutoDetect,
            /// <summary>
            /// Manually set the proxy.
            /// </summary>
            Manual,
        }

        public static class Proxy
        {
            /// <summary>
            /// Gets or sets the type of the proxy.
            /// </summary>
            /// <value>The type of the proxy.</value>
            public static ProxyType ProxyType { get; set; }
            /// <summary>
            /// Gets or sets the proxy address.
            /// </summary>
            /// <value>The address.</value>
            public static string Address { get; set; }
            /// <summary>
            /// Gets or sets the proxy port.
            /// </summary>
            /// <value>The port.</value>
            public static string Port { get; set; }
            /// <summary>
            /// Gets or sets the proxy username.
            /// </summary>
            /// <value>The username.</value>
            public static string Username { get; set; }
            /// <summary>
            /// Gets or sets the proxy password.
            /// </summary>
            /// <value>The password.</value>
            public static string Password { get; set; }
        }
    }
}
